﻿using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Discounts;
using blackhouse.BlackApart.Business.Prices;
using blackhouse.BlackApart.Business.Reservations;
using blackhouse.BlackApart.Data.Caching;
using blackhouse.Data;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;

namespace blackhouse.Aparts.Web.Discounts {
    public class FirstLastMinuteDiscount : IDiscount {

        #region Fields

        private Dictionary<int, FirstLastMinuteData> data;
        private NemoCache cache = new NemoCache(TimeSpan.FromMinutes(2), ConfigurationManager.AppSettings["MSSQLConnectionString"]);
        private AdoDataHelper dataHelper = new MsSqlAdoDataHelper(ConfigurationManager.AppSettings["MSSQLConnectionString"]);

        #endregion

        #region Methods

        public void Apply(Variant variant, DateTime arrivalDate, DateTime departureDate, int peoples) {
            FirstLastMinuteData data = this.GetData(variant.GetGroups()[0].Id);
            this.ApplyFirstTimeDiscount(variant, arrivalDate, departureDate, data);
            this.ApplyLastMinuteDiscount(variant, arrivalDate, departureDate, data);
        }

        private void ApplyFirstTimeDiscount(Variant variant, DateTime arrivalDate, DateTime departureDate, FirstLastMinuteData data) {
            if (arrivalDate.Date >= DateTime.Now.Date + TimeSpan.FromDays(data.FirstDays)) {
                IPriceRabat firstTimeRabat = Factory.Instance().GetPriceRabat("firsttime");
                if (firstTimeRabat != null) {
                    firstTimeRabat.OverrideRabatValue(data.FirstTimeRabat);
                    variant.Price.ApplyPriceRabat(firstTimeRabat);
                }
            }
        }

        private void ApplyLastMinuteDiscount(Variant variant, DateTime arrivalDate, DateTime departureDate, FirstLastMinuteData data) {
            if (arrivalDate.Date <= DateTime.Now.Date + TimeSpan.FromDays(data.LastDays)) {
                IPriceRabat lastminuteRabat = Factory.Instance().GetPriceRabat("lastminute");
                if (lastminuteRabat != null) {
                    lastminuteRabat.OverrideRabatValue(data.LastMinuteRabat);
                    variant.Price.ApplyPriceRabat(lastminuteRabat);
                }
            }
        }

        public void SetXmlConfiguration(System.Xml.XmlElement configurationNode) {

        }

        private FirstLastMinuteData GetData(int apartmentTypeId) {
            if (data == null)
                this.data = this.GetDbData();
            if (this.data.ContainsKey(apartmentTypeId))
                return this.data[apartmentTypeId];
            else
                return default(FirstLastMinuteData);
        }

        protected virtual Dictionary<int, FirstLastMinuteData> GetDbData() {
            cache.Reset();
            cache.SetKey("FirstLastMinute");
            cache.SetDependencyTables("T201");
            Dictionary<int, FirstLastMinuteData> data = cache.GetData<Dictionary<int, FirstLastMinuteData>>();
            if (data == null) {
                data = new Dictionary<int, FirstLastMinuteData>();
                this.dataHelper.Reset();
                this.dataHelper.Query = "SELECT * FROM T201 WHERE del=0";
                IDataReader reader = this.dataHelper.Execute();
                while (reader.Read()) {
                    int apartmentTypeId = Convert.ToInt32(reader["typ_apartamentu"]);
                    FirstLastMinuteData lfData = new FirstLastMinuteData();
                    lfData.FirstDays = Convert.ToInt32(reader["od_ilu_first"]);
                    lfData.LastDays = Convert.ToInt32(reader["do_ilu_last"]);
                    lfData.FirstTimeRabat = Convert.ToSingle(reader["rabat_first"]);
                    lfData.LastMinuteRabat = Convert.ToSingle(reader["rabat_last"]);
                    data.Add(apartmentTypeId, lfData);
                }
                reader.Close();
                cache.SetCaching(data);
            }
            return data;
        }

        #endregion

        #region Struct

        protected struct FirstLastMinuteData {
            public int FirstDays;
            public int LastDays;
            public float FirstTimeRabat;
            public float LastMinuteRabat;
        }

        #endregion

    }

}